using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Xml.Linq;
using Ornament.NHibernateHelper;

namespace Ornament.NHibernates.Configurations
{
    /// <summary>
    /// 
    /// </summary>
    public class MappingCollection : Collection<Mapping>
    {
        private readonly XNamespace xNamespace;
        private XElement sessionFactoryEelement;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sessionFactoryEelement"></param>
        internal MappingCollection(XElement sessionFactoryEelement)
        {
            xNamespace = sessionFactoryEelement.Name.Namespace;
            IEnumerable<XElement> elements = from mappingNode in sessionFactoryEelement.Elements(xNamespace + "mapping")
                                             select mappingNode;
            XElement[] mappings = elements.ToArray<XElement>();

            foreach (XElement node in mappings)
            {
                base.Insert(Count, new Mapping(node));
            }
            this.sessionFactoryEelement = sessionFactoryEelement;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public Mapping CreateMapping()
        {
            var element = new XElement(xNamespace + "mapping");
            return new Mapping(element);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="index"></param>
        /// <param name="item"></param>
        protected override void InsertItem(int index, Mapping item)
        {
            if (sessionFactoryEelement != null)
            {
                sessionFactoryEelement.Add(item.Element);
            }
            base.InsertItem(index, item);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="index"></param>
        protected override void RemoveItem(int index)
        {
            Mapping mapping = this[index];
            mapping.Element.Remove();
            base.RemoveItem(index);
        }

        /// <summary>
        /// 
        /// </summary>
        protected override void ClearItems()
        {
            IEnumerable<XElement> elements = from mappingNode in sessionFactoryEelement.Elements(xNamespace + "mapping")
                                             select mappingNode;
            var a = elements.ToArray<XElement>();
            while (a.Length != 0)
            {
                foreach (XElement ele in a)
                    ele.Remove();
                elements = from mappingNode in sessionFactoryEelement.Elements(xNamespace + "mapping")
                           select mappingNode;
                a = elements.ToArray<XElement>();
            }
            base.ClearItems();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="index"></param>
        /// <param name="item"></param>
        protected override void SetItem(int index, Mapping item)
        {
            Mapping mapping = base[index];
            mapping.Assembly = item.Assembly;
            mapping.File = item.File;
            mapping.Resource = item.Resource;
            base.SetItem(index, item);
        }
    }
}